<!DOCTYPE html>
<html style="display: none;" lang="zh">
    <head>
    <meta charset="utf-8">
    <!--
        © Material Theme
        https://github.com/viosey/hexo-theme-material
        Version: 1.5.2 -->
    <script>
        window.materialVersion = "1.5.2"
        // Delete localstorage with these tags
        window.oldVersion = [
            'codestartv1',
            '1.3.4',
            '1.4.0',
            '1.4.0b1',
            '1.5.0'
        ]
    </script>

    <!-- dns prefetch -->
    <meta http-equiv="x-dns-prefetch-control" content="on">


    <link rel="dns-prefetch" href="https://cdn1.lncld.net"/>













    <!-- Meta & Info -->
    <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
    <meta name="renderer" content="webkit">
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">

    <!-- Title -->
    
    <title>
        
            Docker教程 | 
        
        Selton Blog
    </title>

    <!-- Favicons -->
    <link rel="icon shortcut" type="image/ico" href="/img/header/Taurus.png">
    <link rel="icon" href="/img/favicon.png">

    <meta name="format-detection" content="telephone=no"/>
    <meta name="description" itemprop="description" content="">
    <meta name="keywords" content="docker使用入门教程,tutorial,docker">
    <meta name="theme-color" content="#0097A7">

    <!-- Disable Fucking Bloody Baidu Tranformation -->
    <meta http-equiv="Cache-Control" content="no-transform" />
    <meta http-equiv="Cache-Control" content="no-siteapp" />

    <!--[if lte IE 9]>
        <link rel="stylesheet" href="/css/ie-blocker.css">

        
            <script src="/js/ie-blocker.zhCN.js"></script>
        
    <![endif]-->

    <!-- Import lsloader -->
    <script>(function(){window.lsloader={jsRunSequence:[],jsnamemap:{},cssnamemap:{}};lsloader.removeLS=function(a){try{localStorage.removeItem(a)}catch(b){}};lsloader.setLS=function(a,c){try{localStorage.setItem(a,c)}catch(b){}};lsloader.getLS=function(a){var c="";try{c=localStorage.getItem(a)}catch(b){c=""}return c};versionString="/*"+(window.materialVersion||"unknownVersion")+"*/";lsloader.clean=function(){try{var b=[];for(var a=0;a<localStorage.length;a++){b.push(localStorage.key(a))}b.forEach(function(e){var f=lsloader.getLS(e);if(window.oldVersion){var d=window.oldVersion.reduce(function(g,h){return g||f.indexOf("/*"+h+"*/")!==-1},false);if(d){lsloader.removeLS(e)}}})}catch(c){}};lsloader.clean();lsloader.load=function(f,a,b,d){if(typeof b==="boolean"){d=b;b=undefined}d=d||false;b=b||function(){};var e;e=this.getLS(f);if(e&&e.indexOf(versionString)===-1){this.removeLS(f);this.requestResource(f,a,b,d);return}if(e){var c=e.split(versionString)[0];if(c!=a){console.log("reload:"+a);this.removeLS(f);this.requestResource(f,a,b,d);return}e=e.split(versionString)[1];if(d){this.jsRunSequence.push({name:f,code:e});this.runjs(a,f,e)}else{document.getElementById(f).appendChild(document.createTextNode(e));b()}}else{this.requestResource(f,a,b,d)}};lsloader.requestResource=function(b,e,a,c){var d=this;if(c){this.iojs(e,b,function(h,f,g){d.setLS(f,h+versionString+g);d.runjs(h,f,g)})}else{this.iocss(e,b,function(f){document.getElementById(b).appendChild(document.createTextNode(f));d.setLS(b,e+versionString+f)},a)}};lsloader.iojs=function(d,b,g){var a=this;a.jsRunSequence.push({name:b,code:""});try{var f=new XMLHttpRequest();f.open("get",d,true);f.onreadystatechange=function(){if(f.readyState==4){if((f.status>=200&&f.status<300)||f.status==304){if(f.response!=""){g(d,b,f.response);return}}a.jsfallback(d,b)}};f.send(null)}catch(c){a.jsfallback(d,b)}};lsloader.iocss=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.iofonts=function(f,c,h,a){var b=this;try{var g=new XMLHttpRequest();g.open("get",f,true);g.onreadystatechange=function(){if(g.readyState==4){if((g.status>=200&&g.status<300)||g.status==304){if(g.response!=""){h(g.response);a();return}}b.cssfallback(f,c,a)}};g.send(null)}catch(d){b.cssfallback(f,c,a)}};lsloader.runjs=function(f,c,e){if(!!c&&!!e){for(var b in this.jsRunSequence){if(this.jsRunSequence[b].name==c){this.jsRunSequence[b].code=e}}}if(!!this.jsRunSequence[0]&&!!this.jsRunSequence[0].code&&this.jsRunSequence[0].status!="failed"){var a=document.createElement("script");a.appendChild(document.createTextNode(this.jsRunSequence[0].code));a.type="text/javascript";document.getElementsByTagName("head")[0].appendChild(a);this.jsRunSequence.shift();if(this.jsRunSequence.length>0){this.runjs()}}else{if(!!this.jsRunSequence[0]&&this.jsRunSequence[0].status=="failed"){var d=this;var a=document.createElement("script");a.src=this.jsRunSequence[0].path;a.type="text/javascript";this.jsRunSequence[0].status="loading";a.onload=function(){d.jsRunSequence.shift();if(d.jsRunSequence.length>0){d.runjs()}};document.body.appendChild(a)}}};lsloader.tagLoad=function(b,a){this.jsRunSequence.push({name:a,code:"",path:b,status:"failed"});this.runjs()};lsloader.jsfallback=function(c,b){if(!!this.jsnamemap[b]){return}else{this.jsnamemap[b]=b}for(var a in this.jsRunSequence){if(this.jsRunSequence[a].name==b){this.jsRunSequence[a].code="";this.jsRunSequence[a].status="failed";this.jsRunSequence[a].path=c}}this.runjs()};lsloader.cssfallback=function(e,c,b){if(!!this.cssnamemap[c]){return}else{this.cssnamemap[c]=1}var d=document.createElement("link");d.type="text/css";d.href=e;d.rel="stylesheet";d.onload=d.onerror=b;var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(d,a)};lsloader.runInlineScript=function(c,b){var a=document.getElementById(b).innerText;this.jsRunSequence.push({name:c,code:a});this.runjs()}})();</script>

    <!-- Import queue -->
    <script>function Queue(){this.dataStore=[];this.offer=b;this.poll=d;this.execNext=a;this.debug=false;this.startDebug=c;function b(e){if(this.debug){console.log("Offered a Queued Function.")}if(typeof e==="function"){this.dataStore.push(e)}else{console.log("You must offer a function.")}}function d(){if(this.debug){console.log("Polled a Queued Function.")}return this.dataStore.shift()}function a(){var e=this.poll();if(e!==undefined){if(this.debug){console.log("Run a Queued Function.")}e()}}function c(){this.debug=true}}var queue=new Queue();</script>

    <!-- Import CSS -->
    
        <style id="material_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_css","/css/material.min.css?Z7a72R1E4SxzBKR/WGctOA==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>
        <style id="style_css"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("style_css","/css/style.min.css?MKetZV3cUTfDxvMffaOezg==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>

        

    

    

    <!-- Config CSS -->

<!-- Other Styles -->
<style>
  body, html {
    font-family: Roboto, "Helvetica Neue", Helvetica, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "微软雅黑", Arial, sans-serif;
    overflow-x: hidden !important;
  }
  
  code {
    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
  }

  a {
    color: #00838F;
  }

  .mdl-card__media,
  #search-label,
  #search-form-label:after,
  #scheme-Paradox .hot_tags-count,
  #scheme-Paradox .sidebar_archives-count,
  #scheme-Paradox .sidebar-colored .sidebar-header,
  #scheme-Paradox .sidebar-colored .sidebar-badge{
    background-color: #0097A7 !important;
  }

  /* Sidebar User Drop Down Menu Text Color */
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:hover,
  #scheme-Paradox .sidebar-colored .sidebar-nav>.dropdown>.dropdown-menu>li>a:focus {
    color: #0097A7 !important;
  }

  #post_entry-right-info,
  .sidebar-colored .sidebar-nav li:hover > a,
  .sidebar-colored .sidebar-nav li:hover > a i,
  .sidebar-colored .sidebar-nav li > a:hover,
  .sidebar-colored .sidebar-nav li > a:hover i,
  .sidebar-colored .sidebar-nav li > a:focus i,
  .sidebar-colored .sidebar-nav > .open > a,
  .sidebar-colored .sidebar-nav > .open > a:hover,
  .sidebar-colored .sidebar-nav > .open > a:focus,
  #ds-reset #ds-ctx .ds-ctx-entry .ds-ctx-head a {
    color: #0097A7 !important;
  }

  .toTop {
    background: #757575 !important;
  }

  .material-layout .material-post>.material-nav,
  .material-layout .material-index>.material-nav,
  .material-nav a {
    color: #757575;
  }

  #scheme-Paradox .MD-burger-layer {
    background-color: #757575;
  }

  #scheme-Paradox #post-toc-trigger-btn {
    color: #757575;
  }

  .post-toc a:hover {
    color: #00838F;
    text-decoration: underline;
  }

</style>


<!-- Theme Background Related-->

    <style>
      body{
        background-color: #F5F5F5;
      }

      /* blog_info bottom background */
      #scheme-Paradox .material-layout .something-else .mdl-card__supporting-text{
        background-color: #fff;
      }
    </style>




<!-- Fade Effect -->

    <style>
      .fade {
        transition: all 800ms linear;
        -webkit-transform: translate3d(0,0,0);
        -moz-transform: translate3d(0,0,0);
        -ms-transform: translate3d(0,0,0);
        -o-transform: translate3d(0,0,0);
        transform: translate3d(0,0,0);
        opacity: 1;
      }

      .fade.out{
        opacity: 0;
      }
    </style>


<!-- Import Font -->
<!-- Import Roboto -->

    <link href="https://fonts.googleapis.com/css?family=Roboto:300,400,500" rel="stylesheet">


<!-- Import Material Icons -->


    <style id="material_icons"></style><script>if(typeof window.lsLoadCSSMaxNums === "undefined")window.lsLoadCSSMaxNums = 0;window.lsLoadCSSMaxNums++;lsloader.load("material_icons","/css/material-icons.css?pqhB/Rd/ab0H2+kZp0RDmw==",function(){if(typeof window.lsLoadCSSNums === "undefined")window.lsLoadCSSNums = 0;window.lsLoadCSSNums++;if(window.lsLoadCSSNums == window.lsLoadCSSMaxNums)document.documentElement.style.display="";}, false)</script>




    <!-- Import jQuery -->
    
        <script>lsloader.load("jq_js","/js/jquery.min.js?qcusAULNeBksqffqUM2+Ig==", true)</script>
    

    <!-- WebAPP Icons -->
    <meta name="mobile-web-app-capable" content="yes">
    <meta name="application-name" content="Selton Blog">
    <meta name="msapplication-starturl" content="https://selton.cn/Docker-Tutorial.html">
    <meta name="msapplication-navbutton-color" content="#0097A7">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-title" content="Selton Blog">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon" href="/img/favicon.png">

    <!-- Site Verification -->
    
    

    <!-- RSS -->
    

    <!-- The Open Graph protocol -->
    <meta property="og:url" content="https://selton.cn/Docker-Tutorial.html">
    <meta property="og:type" content="blog">
    <meta property="og:title" content="Docker教程 | Selton Blog">
    <meta property="og:image" content="/img/favicon.png">
    <meta property="og:description" content="">
    <meta property="og:article:tag" content="tutorial"> <meta property="og:article:tag" content="docker"> 

    
        <meta property="article:published_time" content="Tue Oct 09 2018 17:57:26 GMT+0800">
        <meta property="article:modified_time" content="Tue Jan 29 2019 18:35:01 GMT+0800">
    

    <!-- The Twitter Card protocol -->
    <meta name="twitter:card" content="summary_large_image">

    <!-- Add canonical link for SEO -->
    
        <link rel="canonical" href="https://selton.cn/Docker-Tutorial.html" />
    

    <!-- Structured-data for SEO -->
    
        


<script type="application/ld+json">
{
    "@context": "https://schema.org",
    "@type": "BlogPosting",
    "mainEntityOfPage": "https://selton.cn/Docker-Tutorial.html",
    "headline": "Docker教程",
    "datePublished": "Tue Oct 09 2018 17:57:26 GMT+0800",
    "dateModified": "Tue Jan 29 2019 18:35:01 GMT+0800",
    "author": {
        "@type": "Person",
        "name": "Selton",
        "image": {
            "@type": "ImageObject",
            "url": "/img/zh.jpg"
        },
        "description": "你的痛苦俯仰皆是,你的惆怅人皆有之."
    },
    "publisher": {
        "@type": "Organization",
        "name": "Selton Blog",
        "logo": {
            "@type":"ImageObject",
            "url": "/img/favicon.png"
        }
    },
    "keywords": ",tutorial,dockerdocker使用入门教程",
    "description": "",
}
</script>


    

    <!-- Analytics -->
    
    
        <script>
    var _hmt = _hmt || [];
    (function() {var hm = document.createElement('script');
    hm.src = 'https://hm.baidu.com/hm.js?be5a31edaf6d767c1c2470bc9337ac65';
    var s = document.getElementsByTagName('script')[0];
    s.parentNode.insertBefore(hm, s);
    })();
</script>
    
    

    <!-- Custom Head -->
    

</head>


    
        <body id="scheme-Paradox" class="lazy">
            <div class="material-layout  mdl-js-layout has-drawer is-upgraded">
                

                <!-- Main Container -->
                <main class="material-layout__content" id="main">

                    <!-- Top Anchor -->
                    <div id="top"></div>

                    
                        <!-- Hamburger Button -->
                        <button class="MD-burger-icon sidebar-toggle">
                            <span class="MD-burger-layer"></span>
                        </button>
                    

                    <!-- Post TOC -->

    
    <!-- Back Button -->
    <!--
    <div class="material-back" id="backhome-div" tabindex="0">
        <a class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon"
           href="#" onclick="window.history.back();return false;"
           target="_self"
           role="button"
           data-upgraded=",MaterialButton,MaterialRipple">
            <i class="material-icons" role="presentation">arrow_back</i>
            <span class="mdl-button__ripple-container">
                <span class="mdl-ripple"></span>
            </span>
        </a>
    </div>
    -->


    <!-- Left aligned menu below button -->
    
    
    <button id="post-toc-trigger-btn"
        class="mdl-button mdl-js-button mdl-button--icon">
        <i class="material-icons">format_list_numbered</i>
    </button>

    <ul class="post-toc-wrap mdl-menu mdl-menu--bottom-left mdl-js-menu mdl-js-ripple-effect" for="post-toc-trigger-btn" style="max-height:80vh; overflow-y:scroll;">
        <ol class="post-toc"><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#起源"><span class="post-toc-number">1.</span> <span class="post-toc-text">起源</span></a></li><li class="post-toc-item post-toc-level-1"><a class="post-toc-link" href="#快速上手"><span class="post-toc-number">2.</span> <span class="post-toc-text">快速上手</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#安装"><span class="post-toc-number">2.1.</span> <span class="post-toc-text">安装</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Mac"><span class="post-toc-number">2.1.1.</span> <span class="post-toc-text">Mac</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#RedHat"><span class="post-toc-number">2.1.2.</span> <span class="post-toc-text">RedHat</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#Win10"><span class="post-toc-number">2.1.3.</span> <span class="post-toc-text">Win10</span></a></li></ol></li><li class="post-toc-item post-toc-level-2"><a class="post-toc-link" href="#使用"><span class="post-toc-number">2.2.</span> <span class="post-toc-text">使用</span></a><ol class="post-toc-child"><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#构建基本环境"><span class="post-toc-number">2.2.1.</span> <span class="post-toc-text">构建基本环境</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#保存自己的环境"><span class="post-toc-number">2.2.2.</span> <span class="post-toc-text">保存自己的环境</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#将自己的环境提交到远程"><span class="post-toc-number">2.2.3.</span> <span class="post-toc-text">将自己的环境提交到远程</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#同步远程库环境到本地"><span class="post-toc-number">2.2.4.</span> <span class="post-toc-text">同步远程库环境到本地</span></a></li><li class="post-toc-item post-toc-level-3"><a class="post-toc-link" href="#同步远程库环境到linux上-开发-测试-生产"><span class="post-toc-number">2.2.5.</span> <span class="post-toc-text">同步远程库环境到linux上(开发,测试,生产)</span></a></li></ol></li></ol></li></ol>
    </ul>
    




<!-- Layouts -->

    <!-- Post Module -->
    <div class="material-post_container">

        <div class="material-post mdl-grid">
            <div class="mdl-card mdl-shadow--4dp mdl-cell mdl-cell--12-col">

                <!-- Post Header(Thumbnail & Title) -->
                
    <!-- Paradox Post Header -->
    
        
            <!-- Random Thumbnail -->
            <div class="post_thumbnail-random mdl-card__media mdl-color-text--grey-50">
            <script type="text/ls-javascript" id="post-thumbnail-script">
    var randomNum = Math.floor(Math.random() * 19 + 1);

    $('.post_thumbnail-random').attr('data-original', '/img/random/material-' + randomNum + '.png');
    $('.post_thumbnail-random').addClass('lazy');
</script>

        
    
            <p class="article-headline-p">
                Docker教程
            </p>
        </div>





                
                    <!-- Paradox Post Info -->
                    <div class="mdl-color-text--grey-700 mdl-card__supporting-text meta">

    <!-- Author Avatar -->
    <div id="author-avatar">
        <img src="/img/zh.jpg" width="44px" height="44px" alt="Author Avatar"/>
    </div>
    <!-- Author Name & Date -->
    <div>
        <strong>Selton</strong>
        <span>10月 09, 2018</span>
    </div>

    <div class="section-spacer"></div>

    <!-- Favorite -->
    <!--
        <button id="article-functions-like-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon btn-like">
            <i class="material-icons" role="presentation">favorite</i>
            <span class="visuallyhidden">favorites</span>
        </button>
    -->

    <!-- Qrcode -->
    

    <!-- Tags (bookmark) -->
    
    <button id="article-functions-viewtags-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
        <i class="material-icons" role="presentation">bookmark</i>
        <span class="visuallyhidden">bookmark</span>
    </button>
    <ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-functions-viewtags-button">
        <li class="mdl-menu__item">
        <a class="post_tag-link" href="/tags/docker/">docker</a></li><li class="mdl-menu__item"><a class="post_tag-link" href="/tags/tutorial/">tutorial</a>
    </ul>
    

    <!-- Share -->
    
        <button id="article-fuctions-share-button" class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon">
    <i class="material-icons" role="presentation">share</i>
    <span class="visuallyhidden">share</span>
</button>
<ul class="mdl-menu mdl-menu--bottom-right mdl-js-menu mdl-js-ripple-effect" for="article-fuctions-share-button">
    
    <!-- Leancloud Views -->
        <a class="post_share-link" href="#">
            <li class="mdl-menu__item">
                <span id="/Docker-Tutorial.html" class="leancloud-views_num" data-flag-title="Docker教程">
     &nbsp;浏览量
</span>

            </li>
        </a>
    

    

    <!-- Share Weibo -->
    
        <a class="post_share-link" href="http://service.weibo.com/share/share.php?appkey=&title=Docker教程&url=https://selton.cn/Docker-Tutorial.html&pic=https://selton.cn/img/header/Taurus.png&searchPic=false&style=simple" target="_blank">
            <li class="mdl-menu__item">
                分享到微博
            </li>
        </a>
    

    <!-- Share Twitter -->
    
        <a class="post_share-link" href="https://twitter.com/intent/tweet?text=Docker教程&url=https://selton.cn/Docker-Tutorial.html&via=Selton" target="_blank">
            <li class="mdl-menu__item">
                分享到 Twitter
            </li>
        </a>
    

    <!-- Share Facebook -->
    
        <a class="post_share-link" href="https://www.facebook.com/sharer/sharer.php?u=https://selton.cn/Docker-Tutorial.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Facebook
            </li>
        </a>
    

    <!-- Share Google+ -->
    
        <a class="post_share-link" href="https://plus.google.com/share?url=https://selton.cn/Docker-Tutorial.html" target="_blank">
            <li class="mdl-menu__item">
                分享到 Google+
            </li>
        </a>
    

    <!-- Share LinkedIn -->
    

    <!-- Share QQ -->
    

    <!-- Share Telegram -->
    
</ul>

    
</div>

                

                <!-- Post Content -->
                <div id="post-content" class="mdl-color-text--grey-700 mdl-card__supporting-text fade out">
    
        <p>Build，Ship &amp; Run anywhere</p>
<h1 id="起源"><a href="#起源" class="headerlink" title="起源"></a>起源</h1><p>早在十多年前国内外的一些大厂就开始投入研发和使用容器技术，比如Google，对他们来说，使用容器能够充分利用计算资源节省硬件成本，而这几年，真正把容器技术发扬光大的是Docker.</p>
<p>Docker 是一个开源的应用容器引擎，让开发者可以打包他们的应用以及依赖包到一个可移植的容器中，然后发布到任何流行的 Linux 机器上，也可以实现虚拟化。容器是完全使用沙箱机制，相互之间不会有任何接口</p>
<p>Docker的slogan“Build，Ship &amp; Run anywhere”定位非常清晰，Docker的出现打破了传统运维模式里从打包到部署的过程中环境、语言、平台不一致的乱象，将这一整套开发运维模式标准化了，从而真正帮助企业实践了DevOps和微服务化。</p>
<p>但是，国内的大型企业面临技术转型的的时候，历史包袱太沉重，对Docker的接受和部署非常缓慢。同样地，多数的中小型企业也并未把Docker作为生产环境上部署和管理服务的标配，而选择继续使用传统的运维方案。</p>
<p>造成这种现象的原因是什么呢？可能原因之一是企业从业人员对Docker的学习认知并不够。之二是目前市面上Docker的容器编排系统很多，常见的就有K8s、Mesos、Swarm、Rancher、Newben，编排系统的学习和认知成本也进一步提升了企业应用Docker的难度</p>
<p>本文作者同大家一起开始步入docker的镜像世界,一步一步,深入docker,从入门到精通,从使用到理解掌握</p>
<h1 id="快速上手"><a href="#快速上手" class="headerlink" title="快速上手"></a>快速上手</h1><ol>
<li><a href="#安装">安装Docker</a></li>
<li><a href="#使用">使用Docker</a></li>
</ol>
<h2 id="安装"><a href="#安装" class="headerlink" title="安装"></a>安装</h2><ul>
<li><a href="#Mac">mac平台</a></li>
<li><a href="#RedHat">RedHat系Linux平台</a></li>
<li><a href="#Win10">win10平台</a></li>
</ul>
<h3 id="Mac"><a href="#Mac" class="headerlink" title="Mac"></a>Mac</h3><p><strong>Docker基本安装</strong></p>
<p>mac安装了homebrew的话</p>
<p>直接brew cask install docker(我的没有成功,就去官网下载了)</p>
<p>官网下载需要登录帐号 下载的是ce版本</p>
<p>安装完后</p>
<p>启动终端后，通过命令可以是否安装成功</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker info</span><br></pre></td></tr></table></figure>
<p>以及查看docker版本</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker --version</span><br></pre></td></tr></table></figure>
<p><strong>Docker中配置国内镜像</strong></p>
<p>  在正常情况下，docker有一个默认连接的国外官方镜像，在国外的网友访问该官方镜像自然不成问题，但是国内毕竟不是国外，由于国情不同，中国的网络访问国外官方镜像网速一向很慢，而且往往还会遭遇断网的窘境，所以说我们要想正常使用docker的镜像，那么我们就不得不配置相应的国内镜像。</p>
<p>  Docker可以配置的国内镜像有很多可供选择，比如说：阿里云，网易蜂巢，DaoCloud，Docker中国区官方镜像等，这些都是可以提供给大家随意选择的不错的镜像仓库。</p>
<p>在任务栏点击<br>Docker for mac 应用图标(右上方) -&gt; Perferences… -&gt; Daemon -&gt; Registry mirrors</p>
<p>在列表中填写加速器地址即可。用的是网易的<a href="http://hub-mirror.c.163.com" target="_blank" rel="noopener">http://hub-mirror.c.163.com</a> 修改完成之后，点击 Apply &amp; Restart 按钮，Docker 就会重启并应用配置的镜像地址了。</p>
<h3 id="RedHat"><a href="#RedHat" class="headerlink" title="RedHat"></a>RedHat</h3><p><strong>Docker基本安装</strong></p>
<p>使用yum包管理工具安装</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install -y docker</span><br></pre></td></tr></table></figure>
<p>启动docker服务</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">systemctl start docker</span><br></pre></td></tr></table></figure>
<p>查看是否安装成功</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker --version</span><br></pre></td></tr></table></figure>
<p><strong>Docker中配置国内镜像</strong></p>
<p>使用vi修改 /etc/docker/daemon.json 文件</p>
<figure class="highlight json"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">&#123; </span><br><span class="line"><span class="attr">"registry-mirrors"</span>: [<span class="string">"http://hub-mirror.c.163.com"</span>] </span><br><span class="line">&#125;</span><br></pre></td></tr></table></figure>
<p>配置完之后执行下面的命令，以使docker的配置文件生效</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">systemctl daemon-reload </span><br><span class="line">systemctl restart docker</span><br></pre></td></tr></table></figure>
<p>docker info可以查看到修改过的配置</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">Registry Mirrors:</span><br><span class="line"> http://hub-mirror.c.163.com</span><br></pre></td></tr></table></figure>
<h3 id="Win10"><a href="#Win10" class="headerlink" title="Win10"></a>Win10</h3><p><strong>Docker基本安装</strong></p>
<p><strong>Docker中配置国内镜像</strong></p>
<h2 id="使用"><a href="#使用" class="headerlink" title="使用"></a>使用</h2><h3 id="构建基本环境"><a href="#构建基本环境" class="headerlink" title="构建基本环境"></a>构建基本环境</h3><p>安装成功之后,打开终端</p>
<p>确定你想要的操作系统,如果是centos</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker search centos</span><br></pre></td></tr></table></figure>
<p>NAME                               DESCRIPTION                                     STARS               OFFICIAL            AUTOMATED</p>
<p>centos                             The official build of CentOS.                   4773                [OK]</p>
<p>复制这个名字centos</p>
<p>docker seach会在dockerhub,dockerhub(dockerhub类似于github,github大部分用于提交同步代码,dockerhub用于镜像同步与存储)中寻找name和docker search str的这个str相接近的字符串</p>
<blockquote>
<p>镜像:这里可以理解为一个压缩包,这有助于理解</p>
</blockquote>
<p>然后我们将这个远程库中的镜像下拉到本地,在前期,你可以将镜像理解为一个压缩包,这里,就是centos系统的压缩包</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull centos</span><br></pre></td></tr></table></figure>
<p>即可获取到最新的centos版本的镜像</p>
<p>如果需要指明版本</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull centos:版本号</span><br></pre></td></tr></table></figure>
<p> 即可获取到相应版本</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker image ls</span><br></pre></td></tr></table></figure>
<blockquote>
<p>命令简化:docker images</p>
</blockquote>
<p>查看可以使用的所有image的列表</p>
<p>REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE</p>
<p>centos                     latest              5182e96772bf        8 weeks ago         200MB</p>
<p>可以看到我们刚刚pull下来的镜像</p>
<p>TAG表示的版本号,latest表示是最新版,IMAGE ID唯一确定这个镜像,以后都是用这个序列号表示这个镜像</p>
<p>CREATED表示这个镜像是什么时候被创建出来的</p>
<p> SIZE表示这个镜像的大小</p>
<p>接下来我们需要’解压’这个镜像(先不要执行这个命令)</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -it --name mycentos centos /bin/bash</span><br></pre></td></tr></table></figure>
<p>解释:</p>
<p>Docker run 命令用来创建一个新的容器并运行，相当于 docker create和docker start的组合。</p>
<p>用 docker run –help可以显示命令的使用说明。</p>
<p>-i, –interactive                    Keep STDIN open even if not attached(如果没有打开交互界面,则打开)</p>
<p> -t, –tty=false            分配tty设备，该可以支持终端登录，默认为false</p>
<p>带着-it参数会打开一个命令行窗口,退出这个窗口就相当于是’关机’,不过还可以通过docker start的方式’开机’,这也就是docker的前台运行方式,后台运行之后会提到</p>
<blockquote>
<p>参数-t让Docker分配一个伪终端并绑定在容器的标准输入上，-i让容器的标准输入保持打开。</p>
</blockquote>
<p>既然我们要解压这个镜像,就一定得知道这个镜像(‘压缩包’)是谁,centos参数就可以唯一的确定这个’压缩包’,可以唯一标识的只有name:tag或者id,如果像这样只写了name,没有注明tag,一律表示最新版latest,而这里我们正好是latest</p>
<p>–name mycentos –name参数后跟我们解压后的东西的名字mycentos是名字,这样mycentos就能唯一的确定这个解压后的东西,实际上我们之前说了,’压缩包’里压缩的就是一个centos操作系统,所以解压后的东西就是一个centos操作系统</p>
<p>/bin/bash</p>
<p>这是表示载入容器后运行bash ,docker中必须要保持一个进程的运行，要不然整个容器就会退出。</p>
<p>这个就表示启动容器后启动bash。</p>
<p>好的,介绍完了,让我们实际操作试试看</p>
<p>再次确认我们上一步push下来的image</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker image ls</span><br></pre></td></tr></table></figure>
<p>REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE</p>
<p>centos                     latest              5182e96772bf        2 months ago        200MB</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -it --name mycentos centos /bin/bash</span><br></pre></td></tr></table></figure>
<p>如果运行成功,就会变成这样</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">zyfselton@MacBook-Pro-6:docker run -it --name mycentos centos /bin/bash</span><br><span class="line">[root@9f733e598d67 /]#</span><br></pre></td></tr></table></figure>
<p>这就表示我们已经成功的创建并启动和进入了这个centos操作系统</p>
<p>9f733e598d67这个比我们给这个系统起得名字更能唯一标识,但是不容易记忆,需要每次自己查看</p>
<h3 id="保存自己的环境"><a href="#保存自己的环境" class="headerlink" title="保存自己的环境"></a>保存自己的环境</h3><p>然后我们新建一个文件夹</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">mkdir myapp</span><br><span class="line">cd myapp</span><br><span class="line">mkdir work1</span><br></pre></td></tr></table></figure>
<blockquote>
<p>这里的新建文件夹是简单工作,主要是表示我们在这个系统里面做了一些事,我们需要测试我们做的这个事(这里是新建文件夹)能不能被保存到’压缩包’中去,当然你可以在里面安装环境,写笔记,运行程序等等,但是某些需要暴露端口给外部使用的这种服务的安装,后面会详细介绍</p>
</blockquote>
<p>然后我们关闭这个窗口,或者输入exit也可以退出这个窗口</p>
<p>也就相当于关闭了刚才的操作系统</p>
<p>那我们的修改,或者说是工作内容会被清除吗</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">doker ps</span><br></pre></td></tr></table></figure>
<p>会显示所有正在运行的os(Operation System操作系统)</p>
<p>CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES</p>
<p>发现没有</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker ps -a</span><br></pre></td></tr></table></figure>
<p>会显示所有os(不管有没有在启动着)</p>
<p>CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES</p>
<p>9f733e598d67        centos                     “/bin/bash”              9 minutes ago       Exited (0) 2 minutes ago</p>
<p>发现这个id 9f733e598d67和我们之前启动os的id一样,恩,也算是确认过眼神了</p>
<p>这个时候我们要启动它</p>
<p>输入docker start后接 CONTAINER ID就会启动那个os</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker start 9f733e598d67</span><br></pre></td></tr></table></figure>
<p>此时docker ps</p>
<p>CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES</p>
<p>9f733e598d67        centos              “/bin/bash”         45 minutes ago      Up 30 minutes                           mycentos</p>
<p>就会发现我们的系统启动了</p>
<p>可是我们还没有进入到这个系统</p>
<p>进入系统</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">docker exec -it 9f733e598d67 /bin/bash</span><br><span class="line">[root@9f733e598d67 /]#</span><br></pre></td></tr></table></figure>
<p>这里的-it和/bin/bash和之前docker run的那个代表的意思类似</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd myapp</span><br><span class="line">cd work1</span><br></pre></td></tr></table></figure>
<blockquote>
<p>进入容器后的目录为workdir,默认workdir为自己的home(~)下,我们创建的时候在home下,所以地址是没有问题的</p>
</blockquote>
<p>发现我们之前的工作内容都在</p>
<p>这个时候即便exit或者关闭窗口,之后再次进入安装docker环境的机器(就是宿主机,比如我的就是mac环境)的窗口时,我们docker ps</p>
<p>CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES</p>
<p>9f733e598d67        centos              “/bin/bash”         4 hours ago         Up About an hour                        mycentos</p>
<p>然后我们可以将这个带有工作内容的os’压缩’成镜像,这样相当于有了一个压缩包,每次我们解压这个压缩包都会的到一个相应内容的os</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker commit 9f733e598d67 selton/mycentos:1</span><br></pre></td></tr></table></figure>
<p>记得这儿的selton/mycentos:1可以标识这个由9f733e598d67压缩包解压后得到的完整的os</p>
<p>/之前的selton一定要是你的用户名,就是你去docker官网注册的帐号的用户名,没有注册一定要注册一个,不然之后我们无法将压缩包像git提交代码到仓库一样提交我们的压缩包到我们的库</p>
<p>docker image ls就会发现一个新的压缩包</p>
<p>REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE</p>
<p>selton/mycentos              1                   81bc6c9c1684        5 seconds ago       200MB</p>
<p>关闭掉刚才的容器</p>
<p>docker ps</p>
<p>CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES</p>
<p>9f733e598d67        centos              “/bin/bash”         4 hours ago         Up About an hour                        mycentos</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker stop 9f733e598d67</span><br></pre></td></tr></table></figure>
<p>将新的压缩包解压,看看里面有没有我们的工作内容</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -it --name mycentos2 selton/mycentos:1 /bin/bash</span><br></pre></td></tr></table></figure>
<p>–name后面的mycentos2是我们解压后的os的名字,selton/mycentos:1的selton/mycentos是name,1是tag,表示的是具体的某个压缩包</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd myapp</span><br><span class="line">cd work1</span><br></pre></td></tr></table></figure>
<p>发现工作内容都在,至此,我们就明白了docker的主要作用</p>
<p>那么,我们的压缩包是在本地机器上的(这里是mac),但是开发环境和测试环境一定是不一样的,我们如何做到将我们的压缩包让开发环境获取,这就和代码一样,记得我们起初是怎么获得centos的吗</p>
<p>没错,回头看你会发现这个命令docker pull,这和git pull不光长得像,作用也是类似的,用于从远程库中获取到我们的压缩包,不过git中需要先建立本地库和特定远程库的关系,但是我们的docker的镜像库的远程库只有一个,就是dockerhub库</p>
<h3 id="将自己的环境提交到远程"><a href="#将自己的环境提交到远程" class="headerlink" title="将自己的环境提交到远程"></a>将自己的环境提交到远程</h3><p>官方下载docker是需要帐号的,此时我们已经有了帐号,如果没有,请前往官网注册一个帐号</p>
<blockquote>
<p>注意! docker的帐号注册坑有点多,如果你是进入到docker官网,请找到下载页面(我知道你是要注册帐号),下载docker,会需要登录,这时候你就能找到登录页,找到注册按钮:),或者是直接进入dockerhub,首页有注册按钮,注册或者登录的时候有时候会不成功,加载不出来验证你是不是机器人的组件,可能需要翻墙</p>
</blockquote>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker login</span><br></pre></td></tr></table></figure>
<p>会提示让输入用户名:selton</p>
<p>然后就是输入密码</p>
<p>登录需要大概十秒的时间</p>
<p>之后会显示Login Succeeded</p>
<p>如果需要退出,输入docker logout<br>显示如下表示成功退出</p>
<p>Removing login credentials for <a href="https://index.docker.io/v1/" target="_blank" rel="noopener">https://index.docker.io/v1/</a> </p>
<blockquote>
<p>如果你和我一样使用了统一密码管理工具,请记得粘贴使用窗口上的编辑-&gt;paste,而不是cv</p>
</blockquote>
<p>登录成功之后推送我们的镜像到自己的库中</p>
<p>docker images</p>
<p>REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE</p>
<p>myos/mycentos              1                   81bc6c9c1684        19 hours ago        200MB</p>
<p>查看到了我们制作的镜像(‘压缩包’)</p>
<p>然后输入docker push myos/mycentos:1</p>
<p>登录dockerhub就可以看到多了一个你提交的这个镜像(‘’压缩包’’)</p>
<p>也就是现在只要有一台机器安装了docker,就可以得到这个镜像(‘压缩包’),里面除了一个现成的os还有我们可能安装部署完的环境</p>
<h3 id="同步远程库环境到本地"><a href="#同步远程库环境到本地" class="headerlink" title="同步远程库环境到本地"></a>同步远程库环境到本地</h3><p>先尝试一下本地下载远程的我们提交的镜像 </p>
<p>先删除掉本地的</p>
<p>docker images</p>
<p>REPOSITORY                 TAG                 IMAGE ID            CREATED             SIZE</p>
<p>selton/mycentos            1                   e732a1e5c865        About an hour ago   200MB</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker rmi e732a1e5c865</span><br></pre></td></tr></table></figure>
<p>显示</p>
<p>Untagged: selton/mycentos:1</p>
<p>Untagged: selton/mycentos@sha256:8d264bbac07545d8933dcbab286bf343a52bf5a63426b5c4b9d944f4b9acc558</p>
<p>Deleted: sha256:e732a1e5c8652bbb8a48e2ffed6dee7c52df5dfc74f19b0c433b01f2a814417d</p>
<p>Deleted: sha256:3f45206b758eae4a3864432e0e0fda23991d3956a779d4831c1f95dcb4d7191b</p>
<p>docker images查看,ok</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull selton/mycentos:1</span><br></pre></td></tr></table></figure>
<p>就在下载了</p>
<h3 id="同步远程库环境到linux上-开发-测试-生产"><a href="#同步远程库环境到linux上-开发-测试-生产" class="headerlink" title="同步远程库环境到linux上(开发,测试,生产)"></a>同步远程库环境到linux上(开发,测试,生产)</h3><p>我用的是一台阿里云的云服务器,1核2g内存,40g硬盘,centos7</p>
<p>安装docker</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">yum install -y docker</span><br></pre></td></tr></table></figure>
<p>ok</p>
<p>启动docker服务</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">systemctl start docker</span><br><span class="line">docker --version</span><br></pre></td></tr></table></figure>
<p>由于我们刚刚的库就和git的库道理一样,是公开的</p>
<p>无须登录</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker pull selton/mycentos:1</span><br></pre></td></tr></table></figure>
<p>docker images可以查看到</p>
<p>REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE</p>
<p>docker.io/selton/mycentos   1                   e732a1e5c865        6 hours ago         200 MB</p>
<p>之后就和之前的操作一样了</p>
<p>我们再次重复一下以加深印象</p>
<p>现将这个image(‘压缩包’)解压</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">docker run -it --name mycentos e732a1e5c865  /bin/bash</span><br></pre></td></tr></table></figure>
<p>ok,成功进入这个解压出来的container(os)中</p>
<figure class="highlight shell"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">cd myapp</span><br><span class="line">cd work1</span><br></pre></td></tr></table></figure>
<p>ok,至此完成docker的入门使用</p>

        
                <blockquote style="margin: 2em 0 0;padding: 0.5em 1em;border-left: 3px solid #F44336;background-color: #F5F5F5;list-style: none;">
                    <p><strong>
                         
                            转载无须注明出处,就说是自己做的(＝^ω^＝)
                        </strong>
                        <br>
                        <strong>本文链接：</strong><a href="https://selton.cn/Docker-Tutorial.html">https://selton.cn/Docker-Tutorial.html</a>
                    </p>
                </blockquote>
        
    

    
</div>


                

                <!-- Post Comments -->
                
                    
    <div id="comment" style='padding:10px;' class="vcomment"></div>
<script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
<script src="//unpkg.com/valine/dist/Valine.min.js"></script>
<script>
    var GUEST_INFO = ['nick','mail','link'];
    var guest_info = 'nick,mail,link'.split(',').filter(function(item){
        return GUEST_INFO.indexOf(item) > -1
    });
    var notify = 'false' == true;
    var verify = 'false' == true;
    new Valine({
        el: '.vcomment',
        notify: notify,
        verify: verify,
        appId: "bXfVz4s0H1YbOPe8VtjgDWHp-gzGzoHsz",
        appKey: "OJQYQlOupQ3r08BB7AVFOV8o",
        placeholder: "Thank you for reading!",
        pageSize:'10',
        avatar:'identicon',
        lang:'zh-cn'
    });
</script>

                
            </div>

            <!-- Post Prev & Next Nav -->
            <nav class="material-nav mdl-color-text--grey-50 mdl-cell mdl-cell--12-col">
    <!-- Prev Nav -->
    
        <a href="/Primary-SortingAlgorithms1-SortRule.html" id="post_nav-newer" class="prev-content">
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_back</i>
            </button>
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            新篇
        </a>
    

    <!-- Section Spacer -->
    <div class="section-spacer"></div>

    <!-- Next Nav -->
    
        <a href="/log4j2-config.html" id="post_nav-older" class="next-content">
            旧篇
            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
            <button class="mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon mdl-color--white mdl-color-text--grey-900" role="presentation">
                <i class="material-icons">arrow_forward</i>
            </button>
        </a>
    
</nav>

        </div>
    </div>



                    
                        <!-- Overlay For Active Sidebar -->
<div class="sidebar-overlay"></div>

<!-- Material sidebar -->
<aside id="sidebar" class="sidebar sidebar-colored sidebar-fixed-left" role="navigation">
    <div id="sidebar-main">
        <!-- Sidebar Header -->
        <div class="sidebar-header header-cover" style="background-image: url(/img/sidebar_header.png);">
    <!-- Top bar -->
    <div class="top-bar"></div>

    <!-- Sidebar toggle button -->
    <button type="button" class="sidebar-toggle mdl-button mdl-js-button mdl-js-ripple-effect mdl-button--icon" style="display: initial;" data-upgraded=",MaterialButton,MaterialRipple">
        <i class="material-icons">clear_all</i>
        <span class="mdl-button__ripple-container">
            <span class="mdl-ripple">
            </span>
        </span>
    </button>

    <!-- Sidebar Avatar -->
    <div class="sidebar-image">
        <img src="/img/zh.jpg" alt="Selton's avatar">
    </div>

    <!-- Sidebar Email -->
    <a data-toggle="dropdown" class="sidebar-brand" href="#settings-dropdown">
        seltonzyf@gmail.com
        <b class="caret"></b>
    </a>
</div>


        <!-- Sidebar Navigation  -->
        <ul class="nav sidebar-nav">
    <!-- User dropdown  -->
    <li class="dropdown">
        <ul id="settings-dropdown" class="dropdown-menu">
            
                <li>
                    <a href="#" target="_blank" title="Email Me">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        Email Me
                    </a>
                </li>
            
                <li>
                    <a href="https://www.cnblogs.com/selton/" target="_blank" title="博客园">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        博客园
                    </a>
                </li>
            
                <li>
                    <a href="https://www.zhihu.com/people/seltonzyf" target="_blank" title="知乎">
                        
                            <i class="material-icons sidebar-material-icons sidebar-indent-left1pc-element">email</i>
                        
                        知乎
                    </a>
                </li>
            
        </ul>
    </li>

    <!-- Homepage -->
    
        <li id="sidebar-first-li">
            <a href="/">
                
                    <i class="material-icons sidebar-material-icons">home</i>
                
                主页
            </a>
        </li>
        
    

    <!-- Archives  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">inbox</i>
                
                    归档
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
            <li>
                <a class="sidebar_archives-link" href="/archives/2019/01/">一月 2019<span class="sidebar_archives-count">3</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/10/">十月 2018<span class="sidebar_archives-count">2</span></a></li><li><a class="sidebar_archives-link" href="/archives/2018/09/">九月 2018<span class="sidebar_archives-count">4</span></a>
            </ul>
        </li>
        
    

    <!-- Categories  -->
    
        <li class="dropdown">
            <a href="#" class="ripple-effect dropdown-toggle" data-toggle="dropdown">
                
                    <i class="material-icons sidebar-material-icons">chrome_reader_mode</i>
                
                分类
                <b class="caret"></b>
            </a>
            <ul class="dropdown-menu">
                <li>
                
            </ul>
        </li>
        
    

    <!-- Pages  -->
    

    <!-- Article Number  -->
    
</ul>


        <!-- Sidebar Footer -->
        <!--
I'm glad you use this theme, the development is no so easy, I hope you can keep the copyright, I will thank you so much.
If you still want to delete the copyrights, could you still retain the first one? Which namely "Theme Material"
It will not impact the appearance and can give developers a lot of support :)

很高兴您使用并喜欢该主题，开发不易 十分谢谢与希望您可以保留一下版权声明。
如果您仍然想删除的话 能否只保留第一项呢？即 "Theme Material"
它不会影响美观并可以给开发者很大的支持和动力。 :)
-->

<!-- Sidebar Divider -->

    <div class="sidebar-divider"></div>


<!-- Theme Material -->

    <a href="https://github.com/viosey/hexo-theme-material"  class="sidebar-footer-text-a" target="_blank">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
            主题 - Material
            <span class="sidebar-badge badge-circle">i</span>
        </div>
    </a>


<!-- Help & Support -->
<!--

    <a href="mailto:hiviosey@gmail.com" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
        sidebar.help
        <span class="mdl-button__ripple-container">
          <span class="mdl-ripple"></span>
        </span>
      </div>
    </a>

-->

<!-- Feedback -->
<!--

    <a href="https://github.com/viosey/hexo-theme-material/issues" target="_blank" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
        sidebar.feedback
        <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
    </a>

-->

<!-- About Theme -->
<!--

    <a href="https://blog.viosey.com/index.php/Material.html" target="_blank" class="sidebar-footer-text-a">
        <div class="sidebar-text mdl-button mdl-js-button mdl-js-ripple-effect sidebar-footer-text-div" data-upgraded=",MaterialButton,MaterialRipple">
             sidebar.about_theme
            <span class="mdl-button__ripple-container"><span class="mdl-ripple"></span></span></div>
    </a>

-->

    </div>

    <!-- Sidebar Image -->
    

</aside>

                    

                    
                        <!-- Footer Top Button -->
                        <div id="back-to-top" class="toTop-wrap">
    <a href="#top" class="toTop">
        <i class="material-icons footer_top-i">expand_less</i>
    </a>
</div>

                    

                    <!--Footer-->
<footer class="mdl-mini-footer" id="bottom">
    
        <!-- Paradox Footer Left Section -->
        <div class="mdl-mini-footer--left-section sns-list">
    <!-- Twitter -->
    

    <!-- Facebook -->
    

    <!-- Google + -->
    

    <!-- Weibo -->
    

    <!-- Instagram -->
    

    <!-- Tumblr -->
    

    <!-- Github -->
    
        <a href="https://github.com/seltonGitHub" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-github">
                <span class="visuallyhidden">Github</span>
            </button><!--
     --></a>
    

    <!-- LinkedIn -->
    

    <!-- Zhihu -->
    
        <a href="https://www.zhihu.com/people/seltonzyf" target="_blank">
            <button class="mdl-mini-footer--social-btn social-btn footer-sns-zhihu">
                <span class="visuallyhidden">Zhihu</span>
            </button><!--
     --></a>
    

    <!-- Bilibili -->
    

    <!-- Telegram -->
    
    
    <!-- V2EX -->
    
</div>


        <!--Copyright-->
        <div id="copyright">
            Copyright&nbsp;©&nbsp;2018&nbsp;-<script type="text/javascript">var fd = new Date();document.write("&nbsp;" + fd.getFullYear() + "&nbsp;");</script>Selton Blog
            
        </div>

        <!-- Paradox Footer Right Section -->

        <!--
        I am glad you use this theme, the development is no so easy, I hope you can keep the copyright.
        It will not impact the appearance and can give developers a lot of support :)

        很高兴您使用该主题，开发不易，希望您可以保留一下版权声明。
        它不会影响美观并可以给开发者很大的支持。 :)
        -->

        <div class="mdl-mini-footer--right-section">
            <div>
                <div class="footer-develop-div">Powered by <a href="https://hexo.io" target="_blank" class="footer-develop-a">Hexo</a></div>
                <div class="footer-develop-div">Theme - <a href="https://github.com/viosey/hexo-theme-material" target="_blank" class="footer-develop-a">Material</a></div>
            </div>
        </div>
    
</footer>


                    <!-- Import JS File -->

    <script>lsloader.load("lazyload_js","/js/lazyload.min.js?1BcfzuNXqV+ntF6gq+5X3Q==", true)</script>



    <script>lsloader.load("js_js","/js/js.min.js?V/53wGualMuiPM3xoetD5Q==", true)</script>



    <script>lsloader.load("np_js","/js/nprogress.js?pl3Qhb9lvqR1FlyLUna1Yw==", true)</script>


<script type="text/ls-javascript" id="NProgress-script">
    NProgress.configure({
        showSpinner: true
    });
    NProgress.start();
    $('#nprogress .bar').css({
        'background': '#29d'
    });
    $('#nprogress .peg').css({
        'box-shadow': '0 0 10px #29d, 0 0 15px #29d'
    });
    $('#nprogress .spinner-icon').css({
        'border-top-color': '#29d',
        'border-left-color': '#29d'
    });
    setTimeout(function() {
        NProgress.done();
        $('.fade').removeClass('out');
    }, 800);
</script>





    <!-- Leancloud -->
    <script src="https://cdn1.lncld.net/static/js/av-core-mini-0.6.1.js"></script>
    <script>
        AV.initialize('mKudodOwRnXiriu0X9QTbrOR-gzGzoHsz', '7p9Cqu1Elj8CixvXFtn9Flrj');
    </script>
    <script type="text/ls-javascript" id="leancloud-views-script">
    function showTime(Counter) {
        var query = new AV.Query(Counter);
        $('.leancloud-views_num').each(function() {
            var url = $(this).attr('id').trim();
            query.equalTo('url', url);
            query.find({
                success: function(results) {
                    if (results.length === 0) {
                        var content = '0 ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                        return;
                    }
                    for (var i = 0; i < results.length; i++) {
                        var object = results[i];
                        var content = object.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    }
                },
                error: function(object, error) {
                    console.log('Error: ' + error.code + ' ' + error.message);
                }
            });
        });
    }

    function addCount(Counter) {
      var Counter = AV.Object.extend('Counter');
      url = $('.leancloud-views_num').attr('id').trim();
      title = $('.leancloud-views_num').attr('data-flag-title').trim();
      var query = new AV.Query(Counter);
      query.equalTo('url', url);
      query.find({
          success: function(results) {
            if (results.length > 0) {
                var counter = results[0];
                counter.fetchWhenSave(true);
                counter.increment('time');
                counter.save(null, {
                    success: function(counter) {
                        var content =  counter.get('time') + ' ' + $(document.getElementById(url)).text();
                        $(document.getElementById(url)).text(content);
                    },
                    error: function(counter, error) {
                        console.log('Failed to save Visitor num, with error message: ' + error.message);
                    }
                });
            } else {
              var newcounter = new Counter();
              newcounter.set('title', title);
              newcounter.set('url', url);
              newcounter.set('time', 1);
              newcounter.save(null, {
                  success: function(newcounter) {
                      console.log('newcounter.get(\'time\')='+newcounter.get('time'));
                      var content = newcounter.get('time') + ' ' + $(document.getElementById(url)).text();
                      $(document.getElementById(url)).text(content);
                  },
                  error: function(newcounter, error) {
                      console.log('Failed to create');
                  }
              });
            }
        },
        error: function(error) {
            console.log('Error:' + error.code + ' ' + error.message);
        }
      });
    }
    $(function() {
        var Counter = AV.Object.extend('Counter');
        if ($('.leancloud-views_num').length === 1) {
            addCount(Counter);
        } else if ($('.post-title-link').length > 1) {
            showTime(Counter);
        }
    });
</script>






   





<!-- UC Browser Compatible -->
<script>
	var agent = navigator.userAgent.toLowerCase();
	if(agent.indexOf('ucbrowser')>0) {
		document.write('<link rel="stylesheet" href="/css/uc.css">');
	   alert('由于 UC 浏览器使用极旧的内核，而本网站使用了一些新的特性。\n为了您能更好的浏览，推荐使用 Chrome 或 Firefox 浏览器。');
	}
</script>

<!-- Import prettify js  -->


    
        <script>lsloader.load("hanabi","/js/hanabi-browser-bundle.js?Pki5+pzkluqu53g+ouMWpA==", true)</script>
    


<!-- Window Load -->
<!-- add class for prettify -->
<script type="text/ls-javascript" id="window-load">
    $(window).on('load', function() {
        // Post_Toc parent position fixed
        $('.post-toc-wrap').parent('.mdl-menu__container').css('position', 'fixed');
    });

    
    
        
        
        HanabiBrowser.start('pre code',true);
    
</script>

<!-- MathJax Load-->


<!-- Bing Background -->


<script type="text/ls-javascript" id="lazy-load">
    // Offer LazyLoad
    queue.offer(function(){
        $('.lazy').lazyload({
            effect : 'show'
        });
    });

    // Start Queue
    $(document).ready(function(){
        setInterval(function(){
            queue.execNext();
        },200);
    });
</script>

<!-- Custom Footer -->



<script>
    (function(){
        var scriptList = document.querySelectorAll('script[type="text/ls-javascript"]')

        for (var i = 0; i < scriptList.length; ++i) {
            var item = scriptList[i];
            lsloader.runInlineScript(item.id,item.id);
        }
    })()
console.log('\n %c © Material Theme | Version: 1.5.2 | https://github.com/viosey/hexo-theme-material %c \n', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-left-radius:5px;border-bottom-left-radius:5px;', 'color:#455a64;background:#e0e0e0;padding:5px 0;border-top-right-radius:5px;border-bottom-right-radius:5px;');
</script>

                </main>
            </div>
        </body>
    
</html>
